package com.clementheliou.cheliou.business.dataaccess.member.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.clementheliou.cheliou.business.dataaccess.member.MemberDataAccessService;
import com.clementheliou.cheliou.business.dataaccess.member.exception.EMailAlreadyUsedException;
import com.clementheliou.cheliou.dal.dao.member.MemberDAO;
import com.clementheliou.cheliou.dal.dao.member.exception.EMailAlreadyUsedConstraintViolationException;
import com.clementheliou.cheliou.dal.dao.member.impl.MemberHibernateDAO;
import com.clementheliou.cheliou.dal.model.member.Member;

/**
 * {@link MemberDataAccessService} that used the default implementation provided
 * by the model's layer. It should not be used if many implementations are
 * availables in this last one.
 * <p>
 * Due to the {@link Transactional} annotation and the value of its
 * <i>readOnly</i> attribute, all methods are called in a transaction that will
 * be rollbacked in the end. This behavior can be overriden at the method level,
 * more particularly if you need to perform an insert, update or delete action.
 * </p>
 * 
 * @author Clément HELIOU (clement.heliou@gmail.com)
 * @see {@link MemberDataAccessService};
 * @see {@link Service};
 * @see {@link Transactional}.
 * @since 1.0
 */
@Service
@Transactional(readOnly = true)
public class MemberDefaultDataAccessService implements MemberDataAccessService {

	/**
	 * DAO used to attempt the member persistence.
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @see {@link Autowired};
	 * @see {@link MemberDAO}.
	 * @since 1.0
	 */
	@Autowired
	private MemberDAO memberDAO;

	/**
	 * <i>{@inheritDoc}</i>
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @since 1.0
	 */
	@Override
	public Member getMemberByEMail(String email) {
		return memberDAO.getMemberFromEMail(email);
	}

	/**
	 * <i>{@inheritDoc}</i>
	 * <p>
	 * Because we don't know if the given entity is attached to the Hibernate
	 * session, we make use of {@link MemberHibernateDAO#mergeEntity(Member)}.
	 * Then, due to the {@link Transactional} annotation, a commit will be
	 * performed at the end of the method.
	 * </p>
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @see {@link Transactional}.
	 * @since 1.0
	 */
	@Override
	@Transactional(readOnly = false)
	public void updateMember(Member memberToUpdate) {
		memberDAO.mergeEntity(memberToUpdate);
	}

	/**
	 * <i>{@inheritDoc}</i>
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @since 1.0
	 */
	@Override
	@Transactional(readOnly = false)
	public void saveMember(Member memberToSave) throws EMailAlreadyUsedException {
		try {
			memberDAO.saveMember(memberToSave);
		} catch (EMailAlreadyUsedConstraintViolationException e) {
			throw new EMailAlreadyUsedException(e);
		}
	}

}
